/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Design;
using System.ComponentModel;
using System.Windows.Forms.Design;
using System.Windows.Forms;

namespace DaveSexton.DocProject
{
	public abstract class DocProjectOptionsDialogEditorBase<TOptions, TForm> : DocProjectOptionsEditorBase<TOptions>
		where TOptions : DocProjectOptions
		where TForm : Form
	{
		#region Public Properties
		[EditorBrowsable(EditorBrowsableState.Never)]
		public sealed override bool IsDropDownResizable
		{
			[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
			get
			{
				return false;
			}
		}
		#endregion

		#region Private / Protected
		private TForm currentDialog;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="DocProjectOptionsDialogEditorBase" /> class.
		/// </summary>
		protected DocProjectOptionsDialogEditorBase()
		{
		}
		#endregion

		#region Methods
		[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
		public sealed override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
		{
			return UITypeEditorEditStyle.Modal;
		}

		protected override string GetPropertyName(TOptions options, ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			return context.PropertyDescriptor.Name;
		}

		protected abstract TForm CreateDialog(TOptions options, ITypeDescriptorContext context, IServiceProvider provider, object value);

		protected abstract bool HandleChanges(TOptions options, TForm form, DialogResult result);

		protected sealed override bool HandleChanges(TOptions options, object result)
		{
			return HandleChanges(options, currentDialog, (DialogResult) result);
		}

		protected abstract object GetValue(TOptions options, TForm form, DialogResult result);

		protected sealed override object GetValue(TOptions options, object result)
		{
			return GetValue(options, currentDialog, (DialogResult) result);
		}

		protected sealed override void BeforeEdit(TOptions options, ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			currentDialog = CreateDialog(options, context, provider, value);
		}

		protected override object EditValue(TOptions options, ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			IUIService service = options.GetService<IUIService>(provider);

			if (currentDialog != null)
				return (service != null)
					? service.ShowDialog(currentDialog)
					: (DocProjectEnvironment.RunningInVisualStudio)
						? currentDialog.ShowDialog(DocProjectEnvironment.MainWindow)
						: currentDialog.ShowDialog();

			return DialogResult.None;
		}

		protected sealed override bool AfterEdit(TOptions options, ITypeDescriptorContext context, IServiceProvider provider, object value, Exception ex)
		{
			if (currentDialog != null)
			{
				currentDialog.Dispose();
				currentDialog = null;
			}

			return false;	// did not handle exception, in case it was set
		}

		[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public sealed override bool GetPaintValueSupported(ITypeDescriptorContext context)
		{
			return false;
		}

		[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")]
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public sealed override void PaintValue(PaintValueEventArgs e)
		{
			throw new NotSupportedException();
		}
		#endregion
	}
}
